#include "epoint.h"
#include <math.h>

EPoint::EPoint()
{
	m_lon_ED50 = 0;
	m_lat_ED50 = 0;
	m_lon_WGS84 = 0;
	m_lat_WGS84 = 0;

	m_isNull_lat = true ;
	m_isNull_lon = true ;
	m_rif = RIF_WGS84;
}

EPoint::EPoint(const EPoint& p)
{
	 m_lat_ED50 = p.m_lat_ED50;
	 m_lon_ED50 = p.m_lon_ED50;
	m_lat_WGS84 = p.m_lat_WGS84;
	m_lon_WGS84 = p.m_lon_WGS84;
		  m_rif = p.m_rif;
   m_isNull_lat = p.m_isNull_lat;
   m_isNull_lon = p.m_isNull_lon;
}

EPoint & EPoint::operator=(const EPoint& p)
{
	 m_lat_ED50 = p.m_lat_ED50;
	 m_lon_ED50 = p.m_lon_ED50;
	m_lat_WGS84 = p.m_lat_WGS84;
	m_lon_WGS84 = p.m_lon_WGS84;
		  m_rif = p.m_rif;
   m_isNull_lat = p.m_isNull_lat;
   m_isNull_lon = p.m_isNull_lon;
		  return *this;
}

EPoint::EPoint(const double& lon, const double& lat, const int& rif)
{
	set_rif(rif);
	set_lon(lon);
	set_lat(lat);
}

void EPoint::setNull(void)
{
	m_lon_ED50 = 0;
	m_lat_ED50 = 0;
	m_lon_WGS84 = 0;
	m_lat_WGS84 = 0;

	m_isNull_lat = true ;
	m_isNull_lon = true ;
}

bool EPoint::isNull(void) const {
	return (m_isNull_lat || m_isNull_lon);
}

double EPoint::lon (void) const {
	if (m_rif == RIF_WGS84) return m_lon_WGS84;
	if (m_rif == RIF_ED50) return m_lon_ED50;
}

double EPoint::lat (void) const {
	if (m_rif == RIF_WGS84) return m_lat_WGS84;
	if (m_rif == RIF_ED50) return m_lat_ED50;
}

int EPoint::rif (void) const {
	return m_rif;
}

void EPoint::set_lon (const double& val) {
	if (m_rif == RIF_WGS84) {
		m_lon_WGS84 = val;
		m_isNull_lon = false;
	}
	if (m_rif == RIF_ED50) {
		m_lon_ED50 = val;
		m_isNull_lon = false;
	}
}

void EPoint::set_lat (const double& val) {
	if (m_rif == RIF_WGS84) {
		m_lat_WGS84 = val;
		m_isNull_lat = false;
	}
	if (m_rif == RIF_ED50) {
		m_lat_ED50 = val;
		m_isNull_lat = false;
	}
}

void EPoint::set_rif (const int& tprif) {
	if (tprif == RIF_WGS84) {
		m_rif = RIF_WGS84;
	} else if (tprif == RIF_ED50) {
		m_rif = RIF_ED50;
	}
}

double EPoint::dist(const EPoint& from, int& err) const {
	if (isNull() || from.isNull()) {
		err = ERR_EPOINT_NULL;
		return -1;
	}
	if (m_rif == RIF_WGS84) {
		err = ERR_NONE;
		return distanceInMeters_WGS84(from);
	}
	err = ERR_GENERIC;
	return -1;
}

double EPoint::arcInRadians_WGS84(const EPoint& from) const{
	double latitudeArc  = (from.lat() - lat()) * DEG_TO_RAD;
	double longitudeArc = (from.lon() - lon()) * DEG_TO_RAD;
	double latitudeH = sin(latitudeArc * 0.5);
	latitudeH *= latitudeH;
	double lontitudeH = sin(longitudeArc * 0.5);
	lontitudeH *= lontitudeH;
	double tmp = cos(from.lat()*DEG_TO_RAD) * cos(lat()*DEG_TO_RAD);
	return 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
}

double EPoint::distanceInMeters_WGS84(const EPoint& from) const{
	return EARTH_RADIUS_IN_METERS*arcInRadians_WGS84(from);
}

void EPoint::setNull_lon (void){ m_isNull_lon = true ;}
void EPoint::setNull_lat (void){ m_isNull_lat = true ;}

bool EPoint::isNull_lon (void) const {return m_isNull_lon ;}
bool EPoint::isNull_lat (void) const {return m_isNull_lat ;}
